package com.gitee.wsl.android.ui.sample.icon

import android.animation.Animator
import android.animation.ValueAnimator
import android.animation.ValueAnimator.AnimatorUpdateListener
import android.animation.AnimatorListenerAdapter
import android.graphics.*
import android.view.animation.LinearInterpolator

import android.view.animation.AccelerateDecelerateInterpolator



/**
 * Created by codeest on 16/11/13.
 *
 * 嗯..这个控件很带感 隔着屏幕都能感受到声音有木有~
 */
class ENVolumeView : AnimatedIcon() {
    private var mPaint: Paint? = null
    private var mBgPaint: Paint? = null
    private var mPath: Path? = null
    private var mDstPath: Path? = null
    private var mPathMeasure: PathMeasure? = null
    private var mFraction = 0f
    private var mVolumeValue = 0
    private var mCurrentState = STATE_SILENT.toFloat()
    private var mWidth = 0f
    private var mHeight = 0f
    private var mCenterX = 0f
    private var mCenterY = 0f
    private var mBaseLength = 0f
    private var mPathLength = 0f
    private var vibrateAnim: ValueAnimator? = null


    /*constructor(context: Context?) : super(context) {}
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        val ta = context.obtainStyledAttributes(attrs, R.styleable.volume)
        val lineColor = ta.getColor(R.styleable.volume_volume_line_color, DEFAULT_LINE_COLOR)
        val lineWidth = ta.getInteger(R.styleable.volume_volume_line_width, DEFAULT_LINE_WIDTH)
        val bgLineColor =
            ta.getInteger(R.styleable.volume_volume_bg_line_color, DEFAULT_BG_LINE_COLOR)
        val bgLineWidth =
            ta.getInteger(R.styleable.volume_volume_bg_line_width, DEFAULT_BG_LINE_WIDTH)
        ta.recycle()

    }*/

    init {
        mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        mPaint!!.style = Paint.Style.STROKE
        mPaint!!.strokeCap = Paint.Cap.ROUND
        mPaint!!.strokeJoin = Paint.Join.ROUND
        //mPaint!!.color = lineColor
        //mPaint!!.strokeWidth = lineWidth.toFloat()
        mBgPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        mBgPaint!!.style = Paint.Style.STROKE
        mBgPaint!!.strokeCap = Paint.Cap.ROUND
        mBgPaint!!.strokeJoin = Paint.Join.ROUND
        //mBgPaint!!.color = bgLineColor
        //mBgPaint!!.strokeWidth = bgLineWidth.toFloat()
        mPath = Path()
        mDstPath = Path()
        mPathMeasure = PathMeasure()
    }



     fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        mWidth = (w * 5 / 6).toFloat()
        mHeight = h.toFloat()
        mBaseLength = mWidth / 6
        mCenterX = (w / 2).toFloat()
        mCenterY = (h / 2).toFloat()
        mPath!!.moveTo(mCenterX - 3 * mBaseLength, mCenterY)
        mPath!!.lineTo(mCenterX - 3 * mBaseLength, mCenterY - 0.5f * mBaseLength)
        mPath!!.lineTo(mCenterX - 2 * mBaseLength, mCenterY - 0.5f * mBaseLength)
        mPath!!.lineTo(mCenterX, mCenterY - 2 * mBaseLength)
        mPath!!.lineTo(mCenterX, mCenterY + 2 * mBaseLength)
        mPath!!.lineTo(mCenterX - 2 * mBaseLength, mCenterY + 0.5f * mBaseLength)
        mPath!!.lineTo(mCenterX - 3 * mBaseLength, mCenterY + 0.5f * mBaseLength)
        mPath!!.close()
        mPathMeasure!!.setPath(mPath, false)
        mPathLength = mPathMeasure!!.length
        vibrateAnim = ValueAnimator.ofFloat(1f, 100f)
        vibrateAnim!!.setDuration(100)
        vibrateAnim!!.setInterpolator(LinearInterpolator())
        vibrateAnim!!.setRepeatCount(ValueAnimator.INFINITE)
        vibrateAnim!!.setRepeatMode(ValueAnimator.REVERSE)
        vibrateAnim!!.addUpdateListener(AnimatorUpdateListener { valueAnimator ->
            mFraction = valueAnimator.animatedFraction
            invalidateSelf()
        })
    }


    override fun startAnimation()  {
        openVolume()
    }

     fun pause() {
        closeVolume()
    }

     fun setDuration(duration: Int) {

    }

    override fun draw(canvas: Canvas) {

        if (mCurrentState != STATE_VIBRATE.toFloat()) {
            if (mFraction <= 0.5) {
                mDstPath!!.reset() //嗷~ 在这画喇叭
                mPathMeasure!!.getSegment(
                    0f,
                    mPathLength * 0.38f - mPathLength * 0.13f * mFraction,
                    mDstPath,
                    true
                )
                canvas.drawPath(mDstPath!!, mBgPaint!!)
                mDstPath!!.reset()
                mPathMeasure!!.getSegment(
                    mPathLength * 0.62f + mPathLength * 0.13f * mFraction,
                    mPathLength,
                    mDstPath,
                    true
                )
                canvas.drawPath(mDstPath!!, mBgPaint!!)
                canvas.save() //嗷~ 在这画X
                canvas.translate(-mFraction * mBaseLength * 2, 0f)
                canvas.drawLine(
                    mCenterX - mBaseLength * (0.5f - mFraction),
                    mCenterY - mBaseLength * (0.5f - mFraction),
                    mCenterX + mBaseLength * (0.5f - mFraction),
                    mCenterY + mBaseLength * (0.5f - mFraction),
                    mBgPaint!!
                )
                canvas.drawLine(
                    mCenterX - mBaseLength * (0.5f - mFraction),
                    mCenterY + mBaseLength * (0.5f - mFraction),
                    mCenterX + mBaseLength * (0.5f - mFraction),
                    mCenterY - mBaseLength * (0.5f - mFraction),
                    mBgPaint!!
                )
                canvas.restore()
            } else {
                mDstPath!!.reset() //嗷~ 在这画喇叭
                mPathMeasure!!.getSegment(
                    0f,
                    mPathLength * 0.25f + mPathLength * 0.13f * (mFraction - 0.5f),
                    mDstPath,
                    true
                )
                canvas.drawPath(mDstPath!!, mBgPaint!!)
                mDstPath!!.reset()
                mPathMeasure!!.getSegment(
                    mPathLength * 0.75f - mPathLength * 0.13f * (mFraction - 0.5f),
                    mPathLength,
                    mDstPath,
                    true
                )
                canvas.drawPath(mDstPath!!, mBgPaint!!)
                mDstPath!!.reset()
                mPathMeasure!!.getSegment(
                    0f,
                    mPathLength * 0.38f / 0.5f * (mFraction - 0.5f),
                    mDstPath,
                    true
                )
                canvas.drawPath(mDstPath!!, mPaint!!)
                mDstPath!!.reset()
                mPathMeasure!!.getSegment(
                    mPathLength - mPathLength * 0.38f / 0.5f * (mFraction - 0.5f),
                    mPathLength,
                    mDstPath,
                    true
                )
                canvas.drawPath(mDstPath!!, mPaint!!)
                canvas.save() //嗷~ 在这画小声波
                canvas.translate(-(1 - mFraction) * mBaseLength * 2, 0f)
                canvas.drawArc(
                    mCenterX - 0.5f * mBaseLength - mBaseLength / 0.5f * (mFraction - 0.5f),
                    mCenterY - mBaseLength / 0.5f * (mFraction - 0.5f),
                    mCenterX - 0.5f * mBaseLength + mBaseLength / 0.5f * (mFraction - 0.5f),
                    mCenterY + mBaseLength / 0.5f * (mFraction - 0.5f),
                    -55f,
                    110f,
                    false,
                    mBgPaint!!
                )
                var sVolume = mVolumeValue
                if (sVolume > 50) sVolume = 50
                canvas.drawArc(
                    mCenterX - 0.5f * mBaseLength - mBaseLength / 0.5f * (mFraction - 0.5f),
                    mCenterY - mBaseLength / 0.5f * (mFraction - 0.5f),
                    mCenterX - 0.5f * mBaseLength + mBaseLength / 0.5f * (mFraction - 0.5f),
                    mCenterY + mBaseLength / 0.5f * (mFraction - 0.5f),
                    (-55 / 50 * sVolume).toFloat(),
                    (110 / 50 * sVolume).toFloat(),
                    false,
                    mPaint!!
                )
                canvas.restore()
                canvas.save() //嗷~ 在这画大声波
                canvas.translate(-(1 - mFraction) * mBaseLength * 3, 0f)
                canvas.drawArc(
                    mCenterX - 1.6f * mBaseLength / 0.5f * (mFraction - 0.5f),
                    mCenterY - 1.6f * mBaseLength / 0.5f * (mFraction - 0.5f),
                    mCenterX + 1.6f * mBaseLength / 0.5f * (mFraction - 0.5f),
                    mCenterY + 1.6f * mBaseLength / 0.5f * (mFraction - 0.5f),
                    -55f,
                    110f,
                    false,
                    mBgPaint!!
                )
                var lVolume = mVolumeValue - 50
                if (lVolume < 0) lVolume = 0
                canvas.drawArc(
                    mCenterX - 1.6f * mBaseLength / 0.5f * (mFraction - 0.5f),
                    mCenterY - 1.6f * mBaseLength / 0.5f * (mFraction - 0.5f),
                    mCenterX + 1.6f * mBaseLength / 0.5f * (mFraction - 0.5f),
                    mCenterY + 1.6f * mBaseLength / 0.5f * (mFraction - 0.5f),
                    (-55 / 50 * lVolume).toFloat(),
                    (110 / 50 * lVolume).toFloat(),
                    false,
                    mPaint!!
                )
                canvas.restore()
            }
        } else {
            mDstPath!!.reset() //嗷~ 在这画喇叭
            mPathMeasure!!.getSegment(0f, mPathLength * 0.38f, mDstPath, true)
            canvas.drawPath(mDstPath!!, mPaint!!)
            mDstPath!!.reset()
            mPathMeasure!!.getSegment(
                mPathLength - mPathLength * 0.38f,
                mPathLength,
                mDstPath,
                true
            )
            canvas.drawPath(mDstPath!!, mPaint!!)
            canvas.save() //嗷~ 在这画小声波
            canvas.translate(-(1 - mFraction) * mBaseLength / 5 * 2 * mVolumeValue / 100, 0f)
            canvas.drawArc(
                mCenterX - 1.5f * mBaseLength,
                mCenterY - mBaseLength,
                mCenterX + 0.5f * mBaseLength,
                mCenterY + mBaseLength, -55f, 110f, false, mBgPaint!!
            )
            var sVolume = mVolumeValue
            if (sVolume > 50) sVolume = 50
            canvas.drawArc(
                mCenterX - 1.5f * mBaseLength,
                mCenterY - mBaseLength,
                mCenterX + 0.5f * mBaseLength,
                mCenterY + mBaseLength,
                (-55 / 50 * sVolume).toFloat(),
                (110 / 50 * sVolume).toFloat(),
                false,
                mPaint!!
            )
            canvas.restore()
            canvas.save() //嗷~ 在这画大声波
            canvas.translate(-(1 - mFraction) * mBaseLength / 5 * 2 * mVolumeValue / 100, 0f)
            canvas.drawArc(
                mCenterX - 1.6f * mBaseLength,
                mCenterY - 1.6f * mBaseLength,
                mCenterX + 1.6f * mBaseLength,
                mCenterY + 1.6f * mBaseLength, -55f, 110f, false, mBgPaint!!
            )
            var lVolume = mVolumeValue - 50
            if (lVolume < 0) lVolume = 0
            canvas.drawArc(
                mCenterX - 1.6f * mBaseLength,
                mCenterY - 1.6f * mBaseLength,
                mCenterX + 1.6f * mBaseLength,
                mCenterY + 1.6f * mBaseLength,
                (-55 / 50 * lVolume).toFloat(),
                (110 / 50 * lVolume).toFloat(),
                false,
                mPaint!!
            )
            canvas.restore()
        }
    }

    override fun setBounds(left: Int, top: Int, right: Int, bottom: Int) {
        onSizeChanged(left-right,top-bottom,0,0)
    }

    private fun closeVolume() {
        val valueAnimator = ValueAnimator.ofFloat(1f, 100f)
        valueAnimator.duration = 800
        valueAnimator.interpolator = AccelerateDecelerateInterpolator()
        valueAnimator.addUpdateListener { valueAnimator ->
            mFraction = 1 - valueAnimator.animatedFraction
            invalidateSelf()
        }
        if (!valueAnimator.isRunning) {
            valueAnimator.start()
        }
    }

    private fun openVolume() {
        val valueAnimator = ValueAnimator.ofFloat(1f, 100f)
        valueAnimator.duration = 800
        valueAnimator.interpolator = LinearInterpolator()
        valueAnimator.addUpdateListener { valueAnimator ->
            mFraction = valueAnimator.animatedFraction
            invalidateSelf()
        }
        if (!valueAnimator.isRunning) {
            valueAnimator.start()
        }
        valueAnimator.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                if (mVolumeValue == 0) {
                    closeVolume()
                } else {
                    startVibration()
                }
            }
        })
    }

    private fun startVibration() {
        mCurrentState = STATE_VIBRATE.toFloat()
        if (!vibrateAnim!!.isRunning) {
            vibrateAnim!!.start()
        }
    }

    private fun stopVibration() {
        if (vibrateAnim!!.isRunning) {
            vibrateAnim!!.cancel()
        }
    }

    fun updateVolumeValue(value: Int) {
        if (value < 0 || value > 100) {
            return
        }
        mVolumeValue = value
        if (value == 0 && mCurrentState != STATE_SILENT.toFloat()) {
            mCurrentState = STATE_SILENT.toFloat()
            stopVibration()
            closeVolume()
        } else if (value != 0 && mCurrentState == STATE_SILENT.toFloat()) {
            mCurrentState = STATE_VOLUME.toFloat()
            openVolume()
        }
    }

    companion object {
        private const val STATE_SILENT = 0
        private const val STATE_VOLUME = 1
        private const val STATE_VIBRATE = 2
        private const val DEFAULT_LINE_COLOR = Color.WHITE
        private const val DEFAULT_BG_LINE_COLOR = -0x9b9693
        private const val DEFAULT_LINE_WIDTH = 10
        private const val DEFAULT_BG_LINE_WIDTH = 10
    }
}